package com.aisafer.fms.storage;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.aisafer.fms.client.dto.AuthReq;
import com.aisafer.fms.client.dto.DeleteReq;
import com.aisafer.fms.client.dto.DownReq;
import com.aisafer.fms.client.enums.StorageTypeEnums;
import com.aisafer.fms.client.enums.ViewMode;
import com.aisafer.fms.domain.AttachmentE;
import com.aisafer.fms.enums.AttachmentStatusEnums;
import com.aisafer.fms.exception.LocalException;
import com.aisafer.fms.mapper.AttachmentEMapper;
import com.aisafer.fms.mapper.AttachmentMapper;
import com.aisafer.fms.mapper.ModuleMapper;
import com.aisafer.fms.service.IStorageManager;
import com.aisafer.fms.service.impl.AttachmentService;
import com.aliyun.oss.ServiceException;
import com.polaris.base.utils.string.JsonUtil;
import com.polaris.base.utils.string.StringUtils;

/**
 * 本地存储
 * 
 * @author stevin
 *
 */
@Service("LOCAL")
public class Local extends AbstractStorage implements IStorageManager {

	private static final Logger log = LoggerFactory.getLogger(Local.class);

	@Autowired
	private AttachmentService attachmentService;

	@Autowired
	protected AttachmentEMapper attachmentEDao;

	@Autowired
	protected AttachmentMapper attachmentDao;

	@Autowired
	private ModuleMapper moduleDao;

	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
	public void upload(AttachmentE attachmentE, byte[] content) {
		try {
			log.info("localPath:{},attachid:{}", attachConfig.getAttach() + attachmentE.getStorageKey(),
					attachmentE.getAttachid());
			attachmentService.saveAttach(attachmentE, StorageTypeEnums.LOCAL, AttachmentStatusEnums.SUCCESS);
			saveLocal(attachmentE, content);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new LocalException(e.getMessage());
		}
	}

	private void saveLocal(AttachmentE attachmentE, byte[] content) throws IOException {
		File file = new File(attachConfig.getAttach() + attachmentE.getStorageKey());
		if(content != null && content.length > 0) {
			FileUtils.writeByteArrayToFile(file, content);
		}
	}

	@Override
	public byte[] read(DownReq atte) {
		InputStream is = null;
		try {
			File file = new File(attachConfig.getAttach() + atte.getStorageKey());
			is = new FileInputStream(file);
			return IOUtils.toByteArray(is);
		} catch (IOException e) {
			log.error(e.getMessage());
		} finally {
			IOUtils.closeQuietly(is);
		}
		return null;
	}

	@Override
	public String getAuthUrl(AuthReq req) throws ServiceException {
		try {
			final Map<String, Object> param = new HashMap<String, Object>();
			param.put("attachid", req.getAttachid());
			param.put("urlExpire", String.valueOf(getUrlExpire(req)));
			param.put("timestamp", String.valueOf(System.currentTimeMillis()));
			if (req.getHeight() != null && req.getHeight() > 0 && req.getWidth() != null && req.getWidth() > 0) {
				param.put("height", req.getHeight());
				param.put("width", req.getWidth());
			}
			StringBuilder wansb = new StringBuilder();
			
			final String encryptKey = "";//RSAUtils.encryptByPrivateKey(AESUtils.G moduleObj.getRsaPublicKey());
			param.put("sn", "");
			param.put("sk", encryptKey);
			wansb.append(attachConfig.getWanUrl());
			if(ViewMode.VIEW == req.getViewMode()) {
				wansb.append("view/v1/?");
			}else if(ViewMode.DOWN == req.getViewMode()) {
				wansb.append("down/v1/?");
			}else if(ViewMode.BYTE == req.getViewMode()) {
				wansb.append("byte/v1/?");
			}
			else if(ViewMode.BASE64 == req.getViewMode()) {
				wansb.append("base64/v1/?");
			}
			wansb.append(StringUtils.mapConvertUrl(param));
			return String.valueOf(wansb);
		}catch(Exception e) {
			log.error(e.getMessage());
		}
		return "";
	}

	private Long getUrlExpire(AuthReq req) {
		if (req.getUrlExpire() == null || req.getUrlExpire() <= 0) {
			return attachConfig.getUrlDefalutExpire();
		}
		return req.getUrlExpire();
	}


	@Override
	public boolean delete(DeleteReq req) {
		InputStream is = null;
		try {
			File file = new File(attachConfig.getAttach() + req.getStorageKey());
			if(!file.delete()) {
				log.error("delete fail:{}",JsonUtil.bean2Json(req));
			}
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			IOUtils.closeQuietly(is);
		}
		return false;
	}

}
